Skip to content

fix(app-shell,fields,plugin-form,plugin-gantt,plugin-grid,components,console): record pages, forms, drawers and preview cards draw a served object label as served - #30475

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-x9e7d4
Nov 5, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/project-thread-x9e7d4

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Bill · project thread

domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

维护者速读

  • 改了什么:记录页(标题、面包屑、相关列表标题、删除与无权限提示)、记录表单页与新建/编辑弹窗、记录抽屉、预览卡、悬停卡、记录指针单元格、对象引用单元格、只读提示、甘特名称列、页头记录栏、表单视图标题、AI 停靠芯片、动态行与报表索引,统一改为直接显示服务端下发的对象名;只有服务端没下发名称时才查前端翻译目录。
  • 为什么改:客户在 .custom 覆盖里给已安装对象改名后,列表与页头(上一张卡已修)显示新名,但点进记录、表单、抽屉、预览卡仍是基础包的旧译名,同一个东西出现两个名字。
  • 风险与回滚:未改名的对象显示不变(服务端对它下发的就是目录译文);英文不变。风险在于某处对象定义不是按会话语言读来的,那里会显示浏览器语言的名字,已逐处核过(唯一一处裸 fetch 的已打包动作表保持原样)。回滚即 revert 本 PR。
  • 先看:ui/packages/app-shell/src/hooks/servedObjectLabel.ts(新增单数 servedObjectLabel、复数 helper 加 fallback 参数,从 useNavTargetLabel 拆出)、ui/packages/app-shell/src/views/RecordDetailView.tsx(11 处)、ui/packages/app-shell/src/console/AppContent.tsx(弹窗标题与保存提示)。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/hooks/__tests__/servedObjectLabel-30390.test.ts packages/app-shell/src/views/RecordFormPage.listLinkPlural-11733.test.tsx packages/app-shell/src/views/record-preview/RecordPreviewCard.test.tsx,预期全绿,其中 objectstack#30390 分组断言改名后的对象名胜过目录旧译名。
  • 需要你做的:无,席位落地。

Fixes #30390

Clause-②: no
Metadata-protocol: none

What changes

Route 1 of the card (per site), ruled by the seat on the Claim: every Console surface that names a served object draws the served label as given, and asks the client catalog (useObjectLabel) only when no label is served. The rule is the one PR #30388 applied to the list and header surfaces.

  • app-shell: a singular sibling servedObjectLabel next to servedObjectPluralLabel in the private hooks/servedObjectLabel.ts (re-exported by hooks/useNavTargetLabel.ts for its existing importers), and an optional fallback argument on both (client text no server translated, such as the object's name, handed to the catalog lookup as its own last resort, exactly as the sites passed it before). Neither is exported from the package entry, so Clause-②: no. Sites: AppContent (dialog title ×2, save toast, way-back label), ActivityObjectLabel, ConsoleLayout (dock chip), ObjectDataPage (record drawer title), ObjectView (delete confirmation, cascade labels, import wizard), RecordDetailView (related-list titles ×2, phone back and crumb plurals ×2, access-denied and delete copy ×2, cascade labels, record trail ×2, page title ×2), RecordFormPage (title and list link), appReportIndex (plural and singular), RecordPreviewCard, recordDrawerStack (singular and plural), WidgetRefCellFaces (object-ref cell; its label comes from the metadata store's object list).
  • Outside app-shell, each package applies the same rule inline with its own served text: fields RecordHoverCard, plugin-form ObjectFormContainer (save toast) and ClosedAffordanceNotice, plugin-gantt name column, plugin-grid RecordPointerCell, components page-header record chrome, and the Console FormPage form-view heading. The last two are the same-class sites the seat added to the surface.
  • One root changeset, patch for the seven packages.

Tests

  • New pins (an objectstack#30390 describe each): hooks/__tests__/servedObjectLabel-30390.test.ts (helper rule, inline locale map, fallback order); RecordFormPage.listLinkPlural-11733.test.tsx (title, toast and list link of a renamed object); RecordDetailView.relatedListTitlePlural-11733.test.tsx (both related-list producers); record-preview/RecordPreviewCard.test.tsx (card heading); plugin-form/src/closedAffordanceNotice.i18n-11000.test.tsx (notice naming). Each renamed case has a no-label control that the catalog still answers.
  • Reverse verification on 54a922c2: with the pre-change source restored (tree only) the 9 renamed-object cases go RED and every control stays GREEN; restored from HEAD, git diff HEAD empty.
  • Consumer sweep on 54a922c2 (every test file named for, or importing, a changed module, plus every zh-CN fixture file that serves objects; 615 files): 595 passed, 1 skipped, 19 RecordDetailView.* files failed to load because the record page newly reached the metadata provider through useNavTargetLabel's imports. The helpers moved to hooks/servedObjectLabel.ts, a module with no provider imports (useNavTargetLabel re-exports them); the 19 plus 9 pin and importer files re-run: Test Files 28 passed (28), Tests 237 passed (237).
  • Fixtures that served English in a zh-CN session were corrected to serve the zh-CN answer the server would serve, assertions unchanged: RecordDetailView.recordReadFailure-11902, AppContent.createLandingOriginPlural-11733, AppContent.recordSaveToastNamesRecord-26172, InboxPopover.activityObjectLabel-12212, HomeActivity.objectLabel-12238 (the last two test names now say where the label comes from), and the first case of closedAffordanceNotice.i18n-11000.

Acceptance notes

  • Not changed, on purpose: useNavTargetLabel's draft-label rung (a pending draft's label is client text no server translated); objectViewPageHeader (already receives the served plural helper); plugin-detail record-reference-rail (two sites) and record-related-list (no definition in hand, only a humanized name: reported to the seat as out of scope); PackagedActionsSection (its object list is read by a bare fetch without the session's Accept-Language, so its served label is in the browser's language, not the session's; drawing it as given would show English to a zh-CN user with an English browser).

Verification

Gate logs, sweep counts and the reverse leg are in the os-dev report comment on #30390.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Utp6CZgb7dMvMK3Biysr7P


Generated by Claude Code

…console): record surfaces draw a served object label as served

A served object label is already translated by the server (its label order
for an overridden item), so running the client bundle over it again let the
base package's string win a rename back. The record page, form, drawer,
preview card, hover card, pointer cell and the rest of the family now draw the
served label as given and ask the bundle only when none is served.

WIP: tests and changeset follow.

Claude-Session: https://claude.ai/code/session_01Utp6CZgb7dMvMK3Biysr7P
Co-authored-by: Claude <noreply@anthropic.com>
…N fixtures in zh-CN

Claude-Session: https://claude.ai/code/session_01Utp6CZgb7dMvMK3Biysr7P
Co-authored-by: Claude <noreply@anthropic.com>
… with no provider imports

A record surface reading the rule no longer pulls the metadata store into its
module graph.

Claude-Session: https://claude.ai/code/session_01Utp6CZgb7dMvMK3Biysr7P
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 5, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

维护者速读

  • 改了什么:记录页(标题、面包屑、相关列表标题、删除和无权限文案)、记录表单页、控制台新建/编辑弹窗、记录抽屉、预览卡、查找字段悬停卡、记录指针单元格、表单关闭提示、甘特名称列、页头记录区、AI 侧栏、动态行和报表索引,共 39 处,改为直接画服务端下发的对象名;没下发时才查客户端目录,最后才用机器名。
  • 为什么改:列表和页头在 Console sidebar and recent list re-translate an overridden object, list view or app label with the base package's translation, over the server's answer #30311 修好后,这些地方仍让客户端目录先翻译一遍,.custom 扩展把对象改了名,基础包的旧译名就赢回来(Record page, record form, drawer and preview card still show the base translation of an object renamed in a .custom override #30390)。
  • 风险与回滚:未改名的对象,服务端下发的就是目录里的译名,显示不变;英文不变;只是改名后的对象在这些页面上显示新名。回滚即撤本 PR。
  • 先看:ui/packages/app-shell/src/hooks/servedObjectLabel.ts(新增单数 servedObjectLabel),RecordDetailView.tsx 与 RecordFormPage.tsx 的调用点。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/hooks/__tests__/servedObjectLabel-30390.test.ts packages/app-shell/src/views/RecordFormPage.listLinkPlural-11733.test.tsx,全绿。
  • 需要你做的:无,席位落地。
  • 席位意见:可合。

席位核对 — ACCEPT · head 2e89958

  • 形态:31 文件 +486/−177(源码约 +225/−132,其余为测试与 changeset,7 个 patch)。check-governed-merges --pr 30475:NOT governed(0/31 命中),663 行 ≤ 3000。Fixes #30390。
  • 契约复审:Clause-② no。规则 helper 拆进 app-shell 内部模块 hooks/servedObjectLabel.ts(无 provider 依赖),useNavTargetLabel 原样再导出,不进包入口;servedObjectPluralLabel 只加一个可选 fallback 参数。无新 i18n 键、无 spec 改动。Metadata-protocol none。
  • 席位读码:每处都是「服务端 label 原样 → 目录查名 → 机器名/humanize」三级,||/?? 防空串。RecordDetailView 两个 memo 的依赖补了 language。甘特名称列去掉了 useObjectLabel,只在有服务端 label 时用,否则保留通用标题,与原先一致。containers.tsx、RecordHoverCard、closedAffordanceNotice、FormPage 规则同形。
  • 前提实测:报告 6658782766:类型检查 7 包 80/80;新钉测 5 组,反向腿(撤源码)9 红、对照全绿;5 个英文夹具改为下发 zh-CN 答案,断言不变;消费方扫 615 文件,19 个 RecordDetailView.* 因模块依赖加载失败,拆模块后 28/28;派生门禁 36/36 exit 0,0 NOT-MEASURED。
  • 门禁 check-runs:head 上 55 个,44 success、11 skipped(Test Core、Build Core、Build Docs、Dogfood ×2、Temporal、UI Published Artifacts、Plan Test Core shards、Schedule gate、两项 opt-in,ui-only diff 的预期跳过),无红。
  • 接受的偏差:按 Claim 裁定路线 1 外加 components containers.tsx 与 console FormPage.tsx 两处卡外调用点。PackagedActionsSection 未改,理由成立(裸 fetch 不带会话语言,原样画会出浏览器语言)。
  • 范围外去向:plugin-detail 相关列表/引用侧栏(只有对象名)与 packaged-actions 表的对象列 → Record surfaces that know only an object's name still show the base package's translation of a renamed object (related list, reference rail, packaged-actions table) #30486(Blocked-by fix(app-shell,fields,plugin-form,plugin-gantt,plugin-grid,components,console): record pages, forms, drawers and preview cards draw a served object label as served #30475)。
  • 落地条款:中继 pr_ready + automerge_enable;合并后清 pm:dispatched,在 Record page, record form, drawer and preview card still show the base translation of an object renamed in a .custom override #30390 发落地评论。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 5, 2026 13:18
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 5, 2026 13:18
…-x9e7d4

# Conflicts:
#	ui/packages/app-shell/src/views/RecordDetailView.tsx
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG

席位核对 — ACCEPT(head 后移复核)· head 3567f3b

  • 为什么后移:ACCEPT 6658990508 落在 2e899586,之后 PR 与 main 冲突(13:43Z 读到 mergeable_state: dirty,未入队)。卡片线程合入 origin/main(70981e63)为 merge commit 3567f3b9,无 rebase、无 force-push。
  • diff 未变:PR 仍是 31 文件 +486/−177。31 个文件里 30 个 blob 与 2e899586 逐字相同;唯一不同的 ui/packages/app-shell/src/views/RecordDetailView.tsx,本 PR 的 +/− 行与旧 head 逐行相同(27 行 diff 为空),差异只在 main 带进来的上下文。
  • 形态:文件清单不变,check-governed-merges 结论不变(NOT governed,663 行)。Clause-② no,无契约复审。
  • 门禁 check-runs:新 head 上 55 个,44 success、11 skipped(与旧 head 同一组 ui-only 预期跳过),无红。
  • 落地:自动合并仍挂着,14:01Z 已入合并队列。合并后在 Record page, record form, drawer and preview card still show the base translation of an object renamed in a .custom override #30390 发落地评论并清 pm:dispatched。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Record page, record form, drawer and preview card still show the base translation of an object renamed in a .custom override

1 participant